package org.sjs.dreamfly.biz.movie.detail

import android.annotation.SuppressLint
import android.graphics.Typeface
import android.os.Bundle
import android.text.SpannableString
import android.text.Spanned
import android.text.SpannedString
import android.text.style.StyleSpan
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.core.content.res.ResourcesCompat
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.google.common.eventbus.Subscribe
import kotlinx.coroutines.launch
import org.sjs.dreamfly.R
import org.sjs.dreamfly.app.PlayListLoadedEvent
import org.sjs.dreamfly.app.defaultEventBus
import org.sjs.dreamfly.biz.movie.MovieConstants
import org.sjs.dreamfly.biz.movie.MovieUtil
import org.sjs.dreamfly.common.base.BaseActivity
import org.sjs.dreamfly.common.base.BaseFragment
import org.sjs.dreamfly.common.base.BaseViewHolder
import org.sjs.dreamfly.common.base.Listener
import org.sjs.dreamfly.common.base.ListenerOwner
import org.sjs.dreamfly.common.util.LogUtil
import org.sjs.dreamfly.common.util.PhemonUtils
import org.sjs.dreamfly.common.util.Router
import org.sjs.dreamfly.data.Config
import org.sjs.dreamfly.model.MovieInfo
import org.sjs.dreamfly.model.VideoInfo
import java.lang.ref.WeakReference

class MovieDetailFragment : BaseFragment(), ListenerOwner<MovieDetailFragment.ViewClickListener> {

    interface ViewClickListener: Listener {
        override fun notify(vararg params: Any?) {
            val param = params[0] as Array<*>
            onClick(param[0] as View, param[1] as Int)
        }
        fun onClick(view: View, position: Int)
    }

    fun newInstance(channelType: String): MovieDetailFragment {
        val fragment = MovieDetailFragment()
        fragment.arguments = Bundle().apply {
            putString(Router.KEY_CHANNEL_TYPE, channelType)
        }
        return fragment
    }

    private var headerBackgroundView: ImageView? = null
    private var coverView: ImageView? = null
    private var titleView: TextView? = null
    private var subTitleView: TextView? = null
    private var scoreView: TextView? = null
    private var regionView: TextView? = null
    private var yearView: TextView? = null
    private var languageView: TextView? = null
    private var actorsView: TextView? = null
    private var directorView: TextView? = null
    private var btnPlay: TextView? = null
    private var iconLoadingView: View? = null
    private var playListView: RecyclerView? = null
    private lateinit var viewModel: MovieDetailViewModel

    private var channelType = Config.defaultChannelType4XiGua

    override val listeners = mutableListOf<WeakReference<ViewClickListener>>()

    override fun onCreate(savedInstanceState: Bundle?) {
        arguments?.getString(Router.KEY_CHANNEL_TYPE)?.let {
            channelType = it
        }
        super.onCreate(savedInstanceState)
    }
    override fun requireLayoutId(): Int {
        MovieUtil.isSingletonMovie(channelType).let {
            if (it == null) {
                return R.layout.fragment_movie_detail
            } else if(it == true) {
                return R.layout.fragment_movie_detail_single
            } else {
                return R.layout.fragment_movie_detail_multiple
            }
        }
    }

    override fun onInitViewModel() {
        viewModel = ViewModelProvider(activity as BaseActivity).get(MovieDetailViewModel::class.java)
        defaultEventBus.register(this)
    }

    override fun onDestroy() {
        super.onDestroy()
        defaultEventBus.unregister(this)
    }

    override fun onBindViews() {
        val view = requireView()
        headerBackgroundView = view.findViewById(R.id.header_background)
        coverView = view.findViewById(R.id.movie_cover)
        titleView = view.findViewById(R.id.movie_name)
        subTitleView = view.findViewById(R.id.movie_subtitle)
        scoreView = view.findViewById(R.id.movie_score)
        regionView = view.findViewById(R.id.movie_region)
        yearView = view.findViewById(R.id.movie_year)
        languageView = view.findViewById(R.id.movie_language)
        actorsView = view.findViewById(R.id.movie_actors)
        directorView = view.findViewById(R.id.movie_director)
        btnPlay = view.findViewById(R.id.btn_play)
        iconLoadingView = view.findViewById(R.id.icon_loading)
        playListView = view.findViewById(R.id.play_list_view)
    }

    override fun onInitViews() {
        btnPlay?.setOnClickListener {
            notifyListeners(btnPlay, viewModel.getCurrent())
        }
        adjustImageViewHeight()
        playListView?.layoutManager = GridLayoutManager(activity, 8)
        playListView?.adapter = object : RecyclerView.Adapter<VH>() {
            override fun onCreateViewHolder(
                parent: ViewGroup,
                viewType: Int
            ): VH {
                return VH(LayoutInflater
                    .from(activity)
                    .inflate(R.layout.view_holder_movie_detail_play_list_item, null),
                this@MovieDetailFragment, viewModel)
            }

            override fun getItemCount(): Int {
                return viewModel.getMovieInfo()?.videoList?.size ?: 0
            }

            override fun onBindViewHolder(holder: VH, position: Int) {
                holder.bind(viewModel.getMovieInfo()!!.videoList[position], position)
            }
        }
    }

    private fun adjustImageViewHeight() {
        val screenWidth = PhemonUtils.getScreenWidth()
        if (MovieUtil.isSingletonMovie(channelType) == true) {
            this.coverView?.layoutParams?.height = (screenWidth * (671.0 / 480.0)).toInt()
        } else if (MovieUtil.isSingletonMovie(channelType) == false) {
            this.coverView?.layoutParams?.height = (screenWidth * (360.0 / 640.0)).toInt()
        }
    }

    @SuppressLint("NotifyDataSetChanged")
    override fun onLoadData() {
        if (playListView?.adapter != null) {
            playListView?.adapter?.notifyDataSetChanged()
        }
        if (viewModel.isPlayListPrepared()) {
            iconLoadingView?.visibility = View.GONE
            btnPlay?.visibility = View.VISIBLE
        }
        updateViews()
    }

    @SuppressLint("NotifyDataSetChanged")
    @Subscribe()
    private fun onEventPlayListLoaded(event: PlayListLoadedEvent) {
        LogUtil.d("event:${event.playList}")
        mainScope.launch {
            if (viewModel.onPlayListLoaded(event.playList)) {
                playListView?.adapter?.notifyDataSetChanged()
            }
        }
        viewModel.getSniffStatus().recordPlayListSniffed()
    }

    @SuppressLint("SetTextI18n")
    private fun updateViews() {
        viewModel.getMovieInfo()?.let {
            titleView?.text = it.name
            bindText(subTitleView, null, it.subTitle)
            bindText(scoreView, "评分", it.score)
            bindText(regionView, "地区", "${it.region}")
            bindText(yearView, "年份", "${it.year}")
            bindText(languageView, "语言", it.language)
            bindText(actorsView, "演员", it.actors)
            bindText(directorView, "导演", it.direct)
            val imgUrl = getCoverUrl(it)
            coverView?.let { v->
                Glide.with(this).load(imgUrl).into(v)
            }
        }
    }

    private fun getCoverUrl(it: MovieInfo): String? {
        return when(channelType) {
            MovieConstants.CHANNEL_TYPE_DIANSHIJU ->
                it.coverList?.firstOrNull { it.imageStyle == 1 }?.url

            MovieConstants.CHANNEL_TYPE_DIANYING ->
                it.coverList?.firstOrNull { it.imageStyle == 2 }?.url

            else -> it.imageUrl
        }
    }

    @SuppressLint("SetTextI18n")
    private fun bindText(textView: TextView?, prefix: String? = null, value: String? = null) {
        if (!value.isNullOrEmpty()) {
            if (prefix.isNullOrEmpty()) {
                textView?.text = value
            } else {
                textView?.text = buildSpannedString("$prefix: $value")
            }
            textView?.visibility = View.VISIBLE
        } else {
            textView?.visibility = View.GONE
        }
    }

    private fun buildSpannedString(content: String): SpannedString {
        val spannableString = SpannableString(content)
        val boldSpan = StyleSpan(Typeface.BOLD)
//        val colorSpan = ForegroundColorSpan(Color.RED)
        spannableString.setSpan(boldSpan, 0, 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
//        spannableString.setSpan(colorSpan, 0, 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
        return SpannedString.valueOf(spannableString)
    }

    fun onPlayInfoLoaded(url: String, refer: String?) {
        iconLoadingView?.visibility = View.GONE
        btnPlay?.visibility = View.VISIBLE
    }

    class VH(itemView: View,
             private val listenerOwner: ListenerOwner<ViewClickListener>,
             private val viewModel: MovieDetailViewModel
    )
        : BaseViewHolder<VideoInfo>(itemView) {
        override fun bind(data: VideoInfo, position: Int) {
            itemView.findViewById<TextView>(R.id.btn_play_list_item).let {
                it.text = data.title
                data.movieId
                if (viewModel.getCurrent() == position) {
                    it.setBackgroundResource(R.color.primary)
                    it.setTextColor(ResourcesCompat.getColor(it.resources, R.color.white, null))
                } else {
                    it.setBackgroundResource(R.color.background)
                    it.setTextColor(ResourcesCompat.getColor(it.resources, R.color.primary_gray, null))
                }
                it.setOnClickListener {
                    listenerOwner.notifyListeners(it, position)
                }
            }
        }
    }
}